<!-- 起步 -->
<template>
	<div class='container'>
		<a-layout>
			<a-layout-content class='layout-content' ref='content'>
				<a-card>
					<h1>加入购物车</h1>
					<div id="box1" class="box">
						<h2>1. 创建 cart   分支</h2>
						<p>运行如下的命令，基于 master 分支在本地创建 cart  子分支，用来开发分类页面相关的功能：</p>
						<code-mirror :value="code[0]" :options="cmOptions"> </code-mirror>
					</div>
					<div class="box" id="box2">
						<h2>2. 配置 vuex</h2>
						<ol>
							<li>
								<p>在项目根目录中创建 store 文件夹，专门用来存放 vuex 相关的模块</p>
							</li>
							<li>
								<p>在 store 目录上鼠标右键，选择 新建 -> js文件，新建 store.js 文件：</p>
								<el-image style="width: 100%;" :src="srcList[0]" fit="contain"
									:preview-src-list="srcList">
								</el-image>
							</li>
							<li>
								<p>在 store.js 中按照如下 4 个步骤初始化 Store 的实例对象：</p>
								<code-mirror :value="code[1]" :options="cmOptions"> </code-mirror>
							</li>
							<li>
								<p>在 main.js 中导入 store 实例对象并挂载到 Vue 的实例上：</p>
								<code-mirror :value="code[2]" :options="cmOptions"> </code-mirror>
							</li>
						</ol>
					</div>
					<div class="box" id="box3">
						<h2>3. 创建购物车的 store 模块</h2>
						<ol>
							<li>
								<p>在 store 目录上鼠标右键，选择 新建 -> js文件，创建购物车的 store 模块，命名为 cart.js：</p>
								<el-image style="width: 100%;" :src="srcList[1]" fit="contain"
									:preview-src-list="srcList">
								</el-image>
							</li>
							<li>
								<p>在 cart.js 中，初始化如下的 vuex 模块：</p>
								<code-mirror :value="code[3]" :options="cmOptions"> </code-mirror>
							</li>
							<li>
								<p>在 store/store.js 模块中，导入并挂载购物车的 vuex 模块，示例代码如下</p>
								<code-mirror :value="code[4]" :options="cmOptions"> </code-mirror>
							</li>
						</ol>
					</div>
					<div class="box" id="box4">
						<h2>4. 在商品详情页中使用 Store 中的数据</h2>
						<ol>
							<li>
								<p>在 goods_detail.vue 页面中，修改 script 标签中的代码如下：</p>
								<code-mirror :value="code[5]" :options="cmOptions"> </code-mirror>
								<div class="tip">
									注意：今后无论映射 mutations 方法，还是 getters 属性，还是 state 中的数据，都需要指定模块的名称，才能进行映射。
								</div>
							</li>
							<li>
								<p>在页面渲染时，可以直接使用映射过来的数据，例如：</p>
								<code-mirror :value="code[6]" :options="cmOptions1"> </code-mirror>
							</li>
						</ol>
					</div>
					<div class="box" id="box5">
						<h2>5. 实现加入购物车的功能</h2>
						<ol>
							<li>
								<p>在 store 目录下的 cart.js 模块中，封装一个将商品信息加入购物车的 mutations 方法，命名为 addToCart。示例代码如下：</p>
								<code-mirror :value="code[7]" :options="cmOptions"> </code-mirror>
							</li>
							<li>
								<p>在商品详情页面中，通过 mapMutations 这个辅助方法，把 vuex 中 m_cart 模块下的 addToCart 方法映射到当前页面：</p>
								<code-mirror :value="code[8]" :options="cmOptions"> </code-mirror>
							</li>
							<li>
								<p>为商品导航组件 uni-goods-nav 绑定 @buttonClick="buttonClick" 事件处理函数：</p>
								<code-mirror :value="code[9]" :options="cmOptions"> </code-mirror>
							</li>
						</ol>
					</div>
					<div class="box" id="box6">
						<h2>6. 动态统计购物车中商品的总数量</h2>
						<ol>
							<li>
								<p>在 cart.js 模块中，在 getters 节点下定义一个 total 方法，用来统计购物车中商品的总数量：</p>
								<code-mirror :value="code[10]" :options="cmOptions"> </code-mirror>
							</li>
							<li>
								<p>在商品详情页面的 script 标签中，按需导入 mapGetters 方法并进行使用：</p>
								<code-mirror :value="code[11]" :options="cmOptions"> </code-mirror>
							</li>
							<li>
								<p>通过 watch 侦听器，监听计算属性 total 值的变化，从而动态为购物车按钮的徽标赋值：</p>
								<code-mirror :value="code[12]" :options="cmOptions"> </code-mirror>
							</li>
						</ol>
					</div>
					<div class="box" id="box7">
						<h2>7. 持久化存储购物车中的商品</h2>
						<ol>
							<li>
								<p>在 cart.js 模块中，声明一个叫做 saveToStorage 的 mutations 方法，此方法负责将购物车中的数据持久化存储到本地：</p>
								<code-mirror :value="code[13]" :options="cmOptions"> </code-mirror>
							</li>
							<li>
								<p>修改 mutations 节点中的 addToCart 方法，在处理完商品信息后，调用步骤 1 中定义的 saveToStorage 方法：</p>
								<code-mirror :value="code[14]" :options="cmOptions"> </code-mirror>
							</li>
							<li>
								<p>修改 cart.js 模块中的 state 函数，读取本地存储的购物车数据，对 cart 数组进行初始化：</p>
								<code-mirror :value="code[15]" :options="cmOptions"> </code-mirror>
							</li>
						</ol>
					</div>
					<div class="box" id="box8">
						<h2>8. 优化商品详情页的 total 侦听器</h2>
						<ol>
							<li>
								<p>使用普通函数的形式定义的 watch 侦听器，在页面首次加载后不会被调用。因此导致了商品详情页在首次加载完毕之后，不会将商品的总数量显示到商品导航区域：</p>
								<code-mirror :value="code[16]" :options="cmOptions"> </code-mirror>
							</li>
							<li>
								<p>为了防止这个上述问题，可以使用对象的形式来定义 watch 侦听器（详细文档请参考 Vue 官方的 watch 侦听器教程），示例代码如下：</p>
								<code-mirror :value="code[17]" :options="cmOptions"> </code-mirror>
							</li>
						</ol>
					</div>
					<div class="box" id="box9">
						<h2>9. 动态为 tabBar 页面设置数字徽标</h2>
						<div class="tip">
							需求描述：从商品详情页面导航到购物车页面之后，需要为 tabBar 中的购物车动态设置数字徽标。
						</div>
						<ol>
							<li>
								<p>把 Store 中的 total 映射到 cart.vue 中使用：</p>
								<code-mirror :value="code[18]" :options="cmOptions"> </code-mirror>
							</li>
							<li>
								<p>在页面刚显示出来的时候，立即调用 setBadge 方法，为 tabBar 设置数字徽标：</p>
								<code-mirror :value="code[19]" :options="cmOptions"> </code-mirror>
							</li>
							<li>
								<p>在 methods 节点中，声明 setBadge 方法如下，通过 uni.setTabBarBadge() 为 tabBar 设置数字徽标：</p>
								<code-mirror :value="code[20]" :options="cmOptions"> </code-mirror>
							</li>
						</ol>
					</div>
					<div class="box" id="box10">
						<h2>10. 将设置 tabBar 徽标的代码抽离为 mixins</h2>
						<div class="tip">注意：除了要在 cart.vue 页面中设置购物车的数字徽标，还需要在其它 3 个 tabBar 页面中，为购物车设置数字徽标。</div>
						<div class="tip">此时可以使用 Vue 提供的 mixins 特性，提高代码的可维护性。</div>
						<ol>
							<li>
								<p>在项目根目录中新建 mixins 文件夹，并在 mixins 文件夹之下新建 tabbar-badge.js 文件，用来把设置 tabBar 徽标的代码封装为一个 mixin 文件：</p>
								<code-mirror :value="code[21]" :options="cmOptions"> </code-mirror>
							</li>
							<li>
								<p>修改 home.vue，cate.vue，cart.vue，my.vue 这 4 个 tabBar 页面的源代码，分别导入 @/mixins/tabbar-badge.js 模块并进行使用：</p>
								<code-mirror :value="code[22]" :options="cmOptions"> </code-mirror>
							</li>	
						</ol>
					</div>
					
					
				</a-card>
			</a-layout-content>
			<a-layout-sider class='layout-sider' width='300'>
				<a-anchor affix :getContainer='getContainer'  :wrapperStyle="{maxHeight: 'calc( 100vh - 120px)'}" @click="handleClick">
					<a-anchor-link href="#box1" title="1. 创建 cart   分支"></a-anchor-link>
					<a-anchor-link href="#box2" title="2. 配置 vuex"></a-anchor-link>
					<a-anchor-link href="#box3" title="3. 创建购物车的 store 模块"></a-anchor-link>
					<a-anchor-link href="#box4" title="4. 在商品详情页中使用 Store 中的数据"></a-anchor-link>
					<a-anchor-link href="#box5" title="5. 实现加入购物车的功能"></a-anchor-link>
					<a-anchor-link href="#box6" title="6. 动态统计购物车中商品的总数量"></a-anchor-link>
					<a-anchor-link href="#box7" title="7. 持久化存储购物车中的商品"></a-anchor-link>
					<a-anchor-link href="#box8" title="8. 优化商品详情页的 total 侦听器"></a-anchor-link>
					<a-anchor-link href="#box9" title="9. 动态为 tabBar 页面设置数字徽标"></a-anchor-link>
					<a-anchor-link href="#box10" title="10. 将设置 tabBar 徽标的代码抽离为 mixins"></a-anchor-link>
				</a-anchor>
			</a-layout-sider>
		</a-layout>

	</div>
</template>
<script>
	import {
		addShopCar
	} from '../../util/code.js'
	import img1 from '@/assets/addShopCar1.png'
	import img2 from '@/assets/addShopCar2.png'
	export default {
		name: 'addShopCar',
		data() {
			return {
				srcList:[img1,img2],
				cmOptions: {
					mode: "javascript",
					theme: "base16-dark",
					disabled: true
				},
				cmOptions1: {
					mode: "vue",
					theme: "base16-dark",
					disabled: true
				},
				code: addShopCar
			}
		},
		methods: {
			getContainer() {
				return this.$refs.content.$el
			},
			handleClick(e, link) {
				// 阻止点击的默认事件修改路由
				e.preventDefault();
				if (link.href) {
					let ele = document.getElementById(link.href);
					ele && ele.scrollIntoView({
						block: 'start',
						behavior: 'smooth'
					});
				}
			}
		}
	}
</script>
<style scoped>
</style>
